package com.srmt.document.feishu.internal;

import com.srmt.feishu.client.FeishuClient;
import com.lark.oapi.service.docx.v1.model.*;
import com.srmt.document.api.ContentReader;
import com.srmt.document.exception.CellException;
import com.srmt.document.exception.ContentException;
import com.srmt.document.exception.DocumentOperationException;
import com.srmt.document.exception.DocumentNotFoundException;
import com.srmt.document.exception.TableException;
import com.srmt.document.feishu.internal.core.BlockContext;
import com.srmt.document.feishu.internal.core.BlockUtils;
import com.srmt.document.feishu.internal.table.TableOperationStrategy;
import com.srmt.document.feishu.internal.table.TableStrategyFactory;
import com.srmt.document.feishu.internal.table.model.TableContext;
import com.srmt.document.model.ColumnData;
import com.srmt.document.model.RowData;
import com.srmt.document.model.TableData;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * 飞书内容读取器实现（重构版）
 * 
 * 基于BlockContext实现，遵循"一次获取，多次使用"原则。
 * 移除了所有持久化缓存，每个方法都基于最新的文档数据。
 * 
 * @author srmt
 * @since 2.0.0
 */
public class FeishuContentReader implements ContentReader {
    
    private static final Logger logger = LoggerFactory.getLogger(FeishuContentReader.class);
    
    private final FeishuClient client;
    private final TableStrategyFactory strategyFactory;

    /**
     * 使用ApplicationConfig构造（推荐）
     */
    public FeishuContentReader(FeishuClient client) {
        if (client == null) {
            throw new IllegalArgumentException("客户端不能为null");
        }
        this.client = client;
        this.strategyFactory = TableStrategyFactory.create(client);
    }
    
    // ============ 文本读取 ============
    
    @Override
    public String readTextAfter(String docId, String anchorText) throws ContentException {
        logger.debug("读取锚点后的文本 '{}' in document: {}", anchorText, docId);
        
        try {
            // 创建上下文（唯一的API调用）
            BlockContext context = new BlockContext(client, docId);
            
            if (anchorText == null || anchorText.isEmpty()) {
                // 如果没有锚点，读取第一个文本块
                for (Block block : context.getBlocks()) {
                    String text = BlockUtils.extractTextFromBlock(block);
                    if (text != null && !text.isEmpty()) {
                        return text;
                    }
                }
                return "";
            } else {
                // 查找锚点Block
                Block anchorBlock = context.findBlockByAnchor(anchorText);
                if (anchorBlock == null) {
                    // 锚点不存在时应该明确报错，让调用者知道操作失败
                    throw new ContentException("Anchor text 未找到: " + anchorText);
                }
                
                // 获取文本容器
                Text textContainer = BlockUtils.getTextFromBlock(anchorBlock);
                if (textContainer == null || textContainer.getElements() == null) {
                    return "";
                }
                
                // 在TextElement级别查找锚点后的文本
                StringBuilder result = new StringBuilder();
                boolean anchorFound = false;
                
                for (TextElement element : textContainer.getElements()) {
                    String content = BlockUtils.extractTextFromTextElement(element);
                    
                    if (!anchorFound) {
                        if (content.contains(anchorText)) {
                            anchorFound = true;
                            // 提取锚点后的部分
                            int index = content.indexOf(anchorText);
                            String afterAnchor = content.substring(index + anchorText.length());
                            result.append(afterAnchor);
                        }
                    } else {
                        result.append(content);
                    }
                }
                
                // 如果同一个Block内没有更多内容，查找下一个Block
                if (result.length() == 0 || !anchorFound) {
                    List<Block> blocks = context.getBlocks();
                    boolean foundBlock = false;
                    
                    for (Block block : blocks) {
                        if (foundBlock) {
                            String blockText = BlockUtils.extractTextFromBlock(block);
                            if (blockText != null && !blockText.isEmpty()) {
                                return blockText;
                            }
                        } else if (block.getBlockId().equals(anchorBlock.getBlockId())) {
                            foundBlock = true;
                        }
                    }
                }
                
                return result.toString();
            }
            
        } catch (DocumentOperationException e) {
            throw new ContentException("读取锚点后的文本失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof ContentException) {
                throw (ContentException) e;
            }
            throw new ContentException("读取锚点后的文本失败: " + e.getMessage());
        }
    }
    
    @Override
    public String readTextBefore(String docId, String anchorText) throws ContentException {
        logger.debug("读取锚点前的文本 '{}' in document: {}", anchorText, docId);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            // 查找锚点Block
            Block anchorBlock = context.findBlockByAnchor(anchorText);
            if (anchorBlock == null) {
                // 锚点不存在时应该明确报错
                throw new ContentException("Anchor text 未找到: " + anchorText);
            }
            
            // 收集锚点之前的所有文本
            StringBuilder result = new StringBuilder();
            List<Block> blocks = context.getBlocks();
            
            for (Block block : blocks) {
                // 如果到达锚点Block
                if (block.getBlockId().equals(anchorBlock.getBlockId())) {
                    // 处理锚点Block内锚点之前的内容
                    Text textContainer = BlockUtils.getTextFromBlock(block);
                    if (textContainer != null && textContainer.getElements() != null) {
                        for (TextElement element : textContainer.getElements()) {
                            String content = BlockUtils.extractTextFromTextElement(element);
                            
                            if (content.contains(anchorText)) {
                                // 只添加锚点之前的部分
                                int index = content.indexOf(anchorText);
                                if (index > 0) {
                                    result.append(content.substring(0, index));
                                }
                                break;
                            } else {
                                result.append(content);
                            }
                        }
                    }
                    break;
                }
                
                // 添加锚点之前的Block的全部内容
                String text = BlockUtils.extractTextFromBlock(block);
                if (text != null && !text.isEmpty()) {
                    result.append(text);
                }
            }
            
            return result.toString();
            
        } catch (DocumentOperationException e) {
            throw new ContentException("读取锚点前的文本失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof ContentException) {
                throw (ContentException) e;
            }
            throw new ContentException("读取锚点前的文本失败: " + e.getMessage());
        }
    }
    
    @Override
    public String readTextBetween(String docId, String startAnchor, String endAnchor) 
            throws ContentException {
        logger.debug("读取文本,范围从 '{}' and '{}' in document: {}", 
                    startAnchor, endAnchor, docId);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            // 查找起始和结束锚点
            Block startBlock = context.findBlockByAnchor(startAnchor);
            Block endBlock = context.findBlockByAnchor(endAnchor);
            
            if (startBlock == null) {
                throw new ContentException("Start anchor 未找到: " + startAnchor);
            }
            if (endBlock == null) {
                throw new ContentException("End anchor 未找到: " + endAnchor);
            }
            
            StringBuilder result = new StringBuilder();
            
            // 如果在同一个Block内
            if (startBlock.getBlockId().equals(endBlock.getBlockId())) {
                Text textContainer = BlockUtils.getTextFromBlock(startBlock);
                if (textContainer != null && textContainer.getElements() != null) {
                    String fullText = BlockUtils.extractTextFromTextObject(textContainer);
                    
                    int startIndex = fullText.indexOf(startAnchor);
                    int endIndex = fullText.indexOf(endAnchor);
                    
                    if (startIndex >= 0 && endIndex >= 0 && endIndex > startIndex) {
                        result.append(fullText.substring(
                            startIndex + startAnchor.length(), endIndex));
                    }
                }
            } else {
                // 跨越多个Block
                List<Block> blocks = context.getBlocks();
                boolean inRange = false;
                
                for (Block block : blocks) {
                    if (block.getBlockId().equals(startBlock.getBlockId())) {
                        // 读取起始块中锚点之后的内容
                        String text = BlockUtils.extractTextFromBlock(block);
                        int startIndex = text.indexOf(startAnchor);
                        if (startIndex >= 0) {
                            result.append(text.substring(startIndex + startAnchor.length()));
                        }
                        inRange = true;
                    } else if (block.getBlockId().equals(endBlock.getBlockId())) {
                        // 读取结束块中锚点之前的内容
                        String text = BlockUtils.extractTextFromBlock(block);
                        int endIndex = text.indexOf(endAnchor);
                        if (endIndex >= 0) {
                            result.append(text.substring(0, endIndex));
                        }
                        break;
                    } else if (inRange) {
                        // 读取中间块的全部内容
                        String text = BlockUtils.extractTextFromBlock(block);
                        if (text != null && !text.isEmpty()) {
                            result.append(text);
                        }
                    }
                }
            }
            
            return result.toString();
            
        } catch (DocumentOperationException e) {
            throw new ContentException("读取锚点之间的文本失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof ContentException) {
                throw (ContentException) e;
            }
            throw new ContentException("读取锚点之间的文本失败: " + e.getMessage());
        }
    }
    
    @Override
    public String readAllText(String docId) throws ContentException {
        // 验证参数
        if (docId == null || docId.trim().isEmpty()) {
            throw new IllegalArgumentException("文档ID不能为null或空字符串");
        }
        
        logger.debug("读取文档的所有文本: {}", docId);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            StringBuilder result = new StringBuilder();
            
            // 遍历所有Block提取文本
            for (Block block : context.getBlocks()) {
                String text = BlockUtils.extractTextFromBlock(block);
                if (text != null && !text.isEmpty()) {
                    if (result.length() > 0) {
                        result.append("\n");
                    }
                    result.append(text);
                }
            }
            
            return result.toString();
            
        } catch (DocumentNotFoundException e) {
            // Wrap DocumentNotFoundException in ContentException but preserve its type in cause
            ContentException wrapped = new ContentException("Document not found: " + docId, e);
            throw wrapped;
        } catch (DocumentOperationException e) {
            throw new ContentException("读取全部文本失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof ContentException) {
                throw (ContentException) e;
            }
            throw new ContentException("读取全部文本失败: " + e.getMessage());
        }
    }
    
    @Override
    public List<String> searchText(String docId, String searchText) throws ContentException {
        logger.debug("搜索文本 '{}' in document: {}", searchText, docId);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            List<String> results = new ArrayList<>();
            
            // 遍历所有Block查找匹配文本
            for (Block block : context.getBlocks()) {
                String content = BlockUtils.extractTextFromBlock(block);
                if (content != null && !content.isEmpty()) {
                    // 查找所有匹配项
                    int index = 0;
                    while ((index = content.indexOf(searchText, index)) != -1) {
                        // 提取上下文（前后各50个字符）
                        int start = Math.max(0, index - 50);
                        int end = Math.min(content.length(), index + searchText.length() + 50);
                        
                        String contextStr = content.substring(start, end);
                        if (start > 0) {
                            contextStr = "..." + contextStr;
                        }
                        if (end < content.length()) {
                            contextStr = contextStr + "...";
                        }
                        
                        results.add(contextStr);
                        
                        // 移动到下一个可能的匹配位置
                        index += searchText.length();
                    }
                }
            }
            
            return results;
            
        } catch (DocumentOperationException e) {
            throw new ContentException("搜索文本失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof ContentException) {
                throw (ContentException) e;
            }
            throw new ContentException("搜索文本失败: " + e.getMessage());
        }
    }
    
    @Override
    public int getWordCount(String docId) throws ContentException {
        
        try {
            String allText = readAllText(docId);
            // 简单统计：按空格、换行等分割计算单词数
            if (allText == null || allText.isEmpty()) {
                return 0;
            }
            
            // 统计中文字符和英文单词
            int chineseCount = 0;
            int englishWordCount = 0;
            
            // 统计中文字符
            for (char c : allText.toCharArray()) {
                if (c >= 0x4E00 && c <= 0x9FA5) {
                    chineseCount++;
                }
            }
            
            // 统计英文单词（按空格分割）
            String[] words = allText.replaceAll("[\\u4e00-\\u9fa5]", " ")
                    .split("\\s+");
            for (String word : words) {
                if (!word.trim().isEmpty()) {
                    englishWordCount++;
                }
            }
            
            return chineseCount + englishWordCount;
            
        } catch (Exception e) {
            if (e instanceof ContentException) {
                throw (ContentException) e;
            }
            throw new ContentException("获取字数失败: " + e.getMessage());
        }
    }
    
    // ============ 表格读取 - 整表 ============
    
    @Override
    public TableData readTableAfter(String docId, String anchorText) throws TableException {
        logger.debug("读取锚点后的表格 '{}' in document: {}", anchorText, docId);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            // 查找表格
            Block tableBlock = context.findTableAfterAnchor(anchorText);
            if (tableBlock == null) {
                throw new TableException("锚点后未找到表格: " + anchorText);
            }
            
            // 使用策略模式处理
            TableContext tableContext = new TableContext(docId, context, tableBlock);
            TableOperationStrategy strategy = strategyFactory.getStrategy(tableBlock);

            return strategy.convertToTableData(tableContext);
            
        } catch (DocumentOperationException e) {
            throw new TableException("读取表格失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof TableException) {
                throw (TableException) e;
            }
            throw new TableException("读取表格失败: " + e.getMessage());
        }
    }
    
    @Override
    public List<TableData> readAllTables(String docId) throws TableException {
        logger.debug("读取文档的所有表格: {}", docId);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            List<TableData> tables = new ArrayList<>();
            
            // 查找所有表格Block
            for (Block block : context.getBlocks()) {
                if (BlockUtils.isTableBlock(block)) {
                    try {
                        // 使用策略模式处理
                        TableContext tableContext = new TableContext(docId, context, block);
                        TableOperationStrategy strategy = strategyFactory.getStrategy(block);
                        tables.add(strategy.convertToTableData(tableContext));
                    } catch (Exception e) {
                        logger.warn("读取表格失败 {}: {}", block.getBlockId(), e.getMessage());
                    }
                }
            }
            
            return tables;
            
        } catch (DocumentOperationException e) {
            throw new TableException("读取全部表格失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof TableException) {
                throw (TableException) e;
            }
            throw new TableException("读取全部表格失败: " + e.getMessage());
        }
    }
    
    // ============ 表格读取 - 按行 ============

    @Override
    public List<RowData> readTableRows(String docId, String tableAnchor, int startRow, int endRow) 
            throws TableException {
        logger.debug("从带有锚点的表格读取第{}行到第{}行 '{}'", 
                    startRow, endRow, tableAnchor);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            // 查找表格
            Block tableBlock = context.findTableAfterAnchor(tableAnchor);
            if (tableBlock == null) {
                throw new TableException("锚点后未找到表格: " + tableAnchor);
            }
            
            // 创建表格上下文并使用策略模式
            TableContext tableContext = new TableContext(docId, context, tableBlock);
            TableOperationStrategy strategy = strategyFactory.getStrategy(tableBlock);
            
            // 获取表格维度
            int[] dimensions = strategy.getTableDimensions(tableContext);
            int totalRows = dimensions[0];
            int totalCols = dimensions[1];
            
            // 验证行索引范围（索引从1开始，闭区间）
            if (startRow < 1 || startRow > totalRows) {
                throw new TableException(String.format(
                    "Start row index %d is out of bounds (table has %d rows, 1-based indexing)",
                    startRow, totalRows));
            }
            if (endRow < startRow || endRow > totalRows) {
                throw new TableException(String.format(
                    "End row index %d is invalid (must be between %d and %d, inclusive)",
                    endRow, startRow, totalRows));
            }
            
            List<RowData> rows = new ArrayList<>();
            
            // 读取指定范围的行（1-based索引，闭区间[startRow, endRow]）
            for (int row = startRow; row <= endRow; row++) {
                RowData rowData = new RowData();
                List<String> cellValues = new ArrayList<>();
                
                // 读取该行的所有列
                for (int col = 1; col <= totalCols; col++) {
                    String cellContent = strategy.getCellContent(tableContext, row, col);
                    cellValues.add(cellContent != null ? cellContent : "");
                }
                
                rowData.setCells(cellValues);
                rows.add(rowData);
            }
            
            return rows;
            
        } catch (DocumentOperationException e) {
            throw new TableException("读取表格失败 rows: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof TableException) {
                throw (TableException) e;
            }
            throw new TableException("读取表格失败 rows: " + e.getMessage());
        }
    }
    
    // ============ 表格读取 - 按列 ============

    
    @Override
    public List<ColumnData> readTableColumns(String docId, String tableAnchor, 
                                            int startCol, int endCol) throws TableException {
        logger.debug("从带有锚点的表格读取第{}列到第{}列 '{}'", 
                    startCol, endCol, tableAnchor);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            // 查找表格
            Block tableBlock = context.findTableAfterAnchor(tableAnchor);
            if (tableBlock == null) {
                throw new TableException("锚点后未找到表格: " + tableAnchor);
            }
            
            // 创建表格上下文并使用策略模式
            TableContext tableContext = new TableContext(docId, context, tableBlock);
            TableOperationStrategy strategy = strategyFactory.getStrategy(tableBlock);
            
            // 获取表格维度
            int[] dimensions = strategy.getTableDimensions(tableContext);
            int totalRows = dimensions[0];
            int totalCols = dimensions[1];
            
            // 验证列索引范围（索引从1开始，闭区间）
            if (startCol < 1 || startCol > totalCols) {
                throw new TableException(String.format(
                    "Start column index %d is out of bounds (table has %d columns, 1-based indexing)",
                    startCol, totalCols));
            }
            if (endCol < startCol || endCol > totalCols) {
                throw new TableException(String.format(
                    "End column index %d is invalid (must be between %d and %d, inclusive)",
                    endCol, startCol, totalCols));
            }
            
            List<ColumnData> columns = new ArrayList<>();
            
            // 读取指定范围的列（1-based索引，闭区间[startCol, endCol]）
            for (int col = startCol; col <= endCol; col++) {
                List<String> columnCells = new ArrayList<>();
                
                // 读取该列的所有行
                for (int row = 1; row <= totalRows; row++) {
                    String cellContent = strategy.getCellContent(tableContext, row, col);
                    columnCells.add(cellContent != null ? cellContent : "");
                }
                
                columns.add(new ColumnData(columnCells));
            }
            
            return columns;
            
        } catch (DocumentOperationException e) {
            throw new TableException("读取表格失败 columns: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof TableException) {
                throw (TableException) e;
            }
            throw new TableException("读取表格失败 columns: " + e.getMessage());
        }
    }
    
    // ============ 表格读取 - 单元格 ============
    
    @Override
    public String readCellContent(String docId, String tableAnchor, int row, int col) 
            throws CellException {
        logger.debug("从带有锚点的表格读取单元格[{}, {}] '{}'", row, col, tableAnchor);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            // 查找表格
            Block tableBlock = context.findTableAfterAnchor(tableAnchor);
            if (tableBlock == null) {
                throw new CellException("锚点后未找到表格: " + tableAnchor);
            }
            
            // 创建表格上下文并使用策略模式
            TableContext tableContext = new TableContext(docId, context, tableBlock);
            TableOperationStrategy strategy = strategyFactory.getStrategy(tableBlock);
            
            // 获取表格维度并验证索引
            int[] dimensions = strategy.getTableDimensions(tableContext);
            if (row < 1 || row > dimensions[0] ||
                col < 1 || col > dimensions[1]) {
                throw new CellException(String.format(
                    "Cell index out of bounds: [%d, %d], table size is %dx%d",
                    row, col, dimensions[0], dimensions[1]));
            }
            
            // 使用策略读取单元格内容
            String content = strategy.getCellContent(tableContext, row, col);
            
            logger.debug("单元格 [{}, {}] content: {}", row, col, content);
            return content;
            
        } catch (TableException e) {
            throw new CellException("读取单元格内容失败: " + e.getMessage());
        } catch (DocumentOperationException e) {
            throw new CellException("读取单元格内容失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof CellException) {
                throw (CellException) e;
            }
            throw new CellException("读取单元格内容失败: " + e.getMessage());
        }
    }
    
    @Override
    public List<List<String>> readCellsContent(String docId, String tableAnchor, 
                                              int startRow, int startCol, 
                                              int endRow, int endCol) throws CellException {
        logger.debug("从带有锚点的表格读取单元格[{},{}到{},{}] '{}'", 
                    startRow, startCol, endRow, endCol, tableAnchor);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            // 查找表格
            Block tableBlock = context.findTableAfterAnchor(tableAnchor);
            if (tableBlock == null) {
                throw new CellException("锚点后未找到表格: " + tableAnchor);
            }
            
            // 创建表格上下文并使用策略模式
            TableContext tableContext = new TableContext(docId, context, tableBlock);
            TableOperationStrategy strategy = strategyFactory.getStrategy(tableBlock);
            
            // 获取表格维度并验证索引
            int[] dimensions = strategy.getTableDimensions(tableContext);
            if (startRow < 1 || endRow > dimensions[0] ||
                startCol < 1 || endCol > dimensions[1]) {
                throw new CellException(String.format(
                    "Cell range out of bounds: [%d,%d] to [%d,%d], table size is %dx%d",
                    startRow, startCol, endRow, endCol, 
                    dimensions[0], dimensions[1]));
            }
            
            List<List<String>> result = new ArrayList<>();
            
            // 读取指定范围的单元格（endRow和endCol为不包含的结束索引）
            for (int row = startRow; row <= endRow && row <= dimensions[0]; row++) {
                List<String> rowCells = new ArrayList<>();
                for (int col = startCol; col <= endCol && col <= dimensions[1]; col++) {
                    rowCells.add(strategy.getCellContent(tableContext, row, col));
                }
                result.add(rowCells);
            }
            
            return result;
            
        } catch (TableException e) {
            throw new CellException("读取单元格内容失败: " + e.getMessage());
        } catch (DocumentOperationException e) {
            throw new CellException("读取单元格内容失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof CellException) {
                throw (CellException) e;
            }
            throw new CellException("读取单元格内容失败: " + e.getMessage());
        }
    }
    
    @Override
    public boolean isMergedCell(String docId, String tableAnchor, int row, int column) 
            throws CellException {
        logger.debug("检查单元格[{}, {}]在带有锚点的表格中是否已合并 '{}'", 
                    row, column, tableAnchor);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            // 查找表格
            Block tableBlock = context.findTableAfterAnchor(tableAnchor);
            if (tableBlock == null) {
                throw new CellException("锚点后未找到表格: " + tableAnchor);
            }
            
            // 创建表格上下文并使用策略模式
            TableContext tableContext = new TableContext(docId, context, tableBlock);
            TableOperationStrategy strategy = strategyFactory.getStrategy(tableBlock);
            
            // 使用策略检查是否为合并单元格
            return strategy.isMergedCell(tableContext, row, column);
            
        } catch (TableException e) {
            throw new CellException("检查合并单元格失败: " + e.getMessage());
        } catch (DocumentOperationException e) {
            throw new CellException("检查合并单元格失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof CellException) {
                throw (CellException) e;
            }
            throw new CellException("检查合并单元格失败: " + e.getMessage());
        }
    }
    
    @Override
    public List<String> readCellsNextToMergedCell(String docId, String tableAnchor, String cellText) 
            throws CellException {
        logger.debug("读取带有锚点的表格中文本为'{}'的合并单元格旁边的单元格 '{}'", 
                    cellText, tableAnchor);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            // 查找表格
            Block tableBlock = context.findTableAfterAnchor(tableAnchor);
            if (tableBlock == null) {
                throw new CellException("锚点后未找到表格: " + tableAnchor);
            }
            
            // 创建表格上下文并使用策略模式
            TableContext tableContext = new TableContext(docId, context, tableBlock);
            TableOperationStrategy strategy = strategyFactory.getStrategy(tableBlock);

            // 获取表格维度
            int[] dimensions = strategy.getTableDimensions(tableContext);
            
            // 查找包含指定文本的合并单元格
            int mergedCellRow = -1;
            int mergedCellCol = -1;
            int mergedRowSpan = 0;
            int mergedColSpan = 0;
            
            for (int row = 1; row <= dimensions[0]; row++) {
                for (int col = 1; col <= dimensions[1]; col++) {
                    String content = strategy.getCellContent(tableContext, row, col);
                    if (content != null && content.contains(cellText)) {
                        // 检查是否是合并单元格
                        if (strategy.isMergedCell(tableContext, row, col)) {
                            int[] span = strategy.getCellSpan(tableContext, row, col);
                            if (span[0] > 1 || span[1] > 1) {
                                mergedCellRow = row;
                                mergedCellCol = col;
                                mergedRowSpan = span[0];
                                mergedColSpan = span[1];
                                break;
                            }
                        }
                    }
                }
                if (mergedCellRow != -1) break;
            }
            
            if (mergedCellRow == -1) {
                throw new CellException("未找到包含文本的合并单元格");
            }
            
            // 读取合并单元格右侧的普通单元格
            List<String> values = new ArrayList<>();
            int targetCol = mergedCellCol + mergedColSpan;
            
            for (int row = mergedCellRow; row < mergedCellRow + mergedRowSpan; row++) {
                if (targetCol <= dimensions[1]) {
                    String value = strategy.getCellContent(tableContext, row, targetCol);
                    values.add(value != null ? value : "");
                }
            }
            
            return values;
            
        } catch (TableException e) {
            throw new CellException("读取合并单元格值失败: " + e.getMessage());
        } catch (DocumentOperationException e) {
            throw new CellException("读取合并单元格值失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof CellException) {
                throw (CellException) e;
            }
            throw new CellException("读取合并单元格值失败: " + e.getMessage());
        }
    }
    
    @Override
    public int getTableRowCount(String docId, String tableAnchor) throws TableException {
        logger.debug("获取带有锚点的表格的行数 '{}'", tableAnchor);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            // 查找表格
            Block tableBlock = context.findTableAfterAnchor(tableAnchor);
            if (tableBlock == null) {
                throw new TableException("锚点后未找到表格: " + tableAnchor);
            }
            
            // 直接使用BlockContext获取维度
            int[] dimensions = context.getTableDimensions(tableBlock.getBlockId());
            return dimensions[0];
            
        } catch (DocumentOperationException e) {
            throw new TableException("获取表格行数失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof TableException) {
                throw (TableException) e;
            }
            throw new TableException("获取表格行数失败: " + e.getMessage());
        }
    }
    
    @Override
    public int getTableColumnCount(String docId, String tableAnchor) throws TableException {
        logger.debug("获取带有锚点的表格的列数 '{}'", tableAnchor);
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, docId);
            
            // 查找表格
            Block tableBlock = context.findTableAfterAnchor(tableAnchor);
            if (tableBlock == null) {
                throw new TableException("锚点后未找到表格: " + tableAnchor);
            }
            
            // 直接使用BlockContext获取维度
            int[] dimensions = context.getTableDimensions(tableBlock.getBlockId());
            return dimensions[1];
            
        } catch (DocumentOperationException e) {
            throw new TableException("获取表格列数失败: " + e.getMessage());
        } catch (Exception e) {
            if (e instanceof TableException) {
                throw (TableException) e;
            }
            throw new TableException("获取表格列数失败: " + e.getMessage());
        }
    }
}